import { createFilter } from '@rollup/pluginutils'
import { FilterPattern, Plugin } from 'vite'
import MagicString from 'magic-string'

type Options = {
  include?: FilterPattern
  exclude?: FilterPattern
  /**
   * 启用插件的mode
   * @default ['production']
   */
  enabledModes?: string[]
  /**
   * Custom properties to remove
   * @example ['data-test', 'data-e2e']
   */
  removeProperties: string[]
}

/**
 * 移除标签上的某些属性, 例如 `data-test`, `data-e2e`等仅用于测试的自定义属性
 */
export function removeTagProperties(opts: Options): Plugin {
  if (!Array.isArray(opts.removeProperties)) {
    throw new Error('customProperties must be an array')
  }

  const { removeProperties, enabledModes, include, exclude }: Required<Options> = {
    include: ['**/*.vue', '**/*.tsx', '**/*.jsx'],
    exclude: 'node_modules/**',
    enabledModes: ['production'],
    ...opts
  }

  const filter = createFilter(include, exclude)
  const regExp = new RegExp(`(${removeProperties.join('|')})="[^"]*"`, 'g')

  let isNeedSourceMap: boolean

  return {
    name: 'remove-tag-properties',
    apply({ build }, { mode }) {
      const sourceMap = build?.sourcemap ?? false
      isNeedSourceMap = [true, 'inline'].includes(sourceMap)

      return enabledModes.includes(mode) && removeProperties.length > 0
    },
    transform(code, id) {
      if (!filter(id)) return null

      if (isNeedSourceMap) {
        const magicString = new MagicString(code)

        magicString.replaceAll(regExp, '')

        return {
          code: magicString.toString(),
          map: magicString.generateMap({ hires: true })
        }
      }

      return {
        code: code.replaceAll(regExp, ''),
        map: null
      }
    }
  }
}
